package com.luojialong.utils;

import com.luojialong.config.MinioConfig;
import com.luojialong.model.request.file.FileSearchRequest;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

@Component
public class MinioUtils {

    @Resource
    private MinioClient minioClient;


    @Resource
    private MinioConfig minioConfig;


    public boolean isExist(String bucket) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        boolean b = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
        return b;
    }

    public boolean createBucket(String bucket) throws Exception {
        minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
        return false;
    }

    public List<Bucket> listBucket() throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        return minioClient.listBuckets();
    }

    public void deleteBucket(String bucket) throws Exception {
        minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());
    }

    public String uploadObject(MultipartFile uploadFile, Long userId, String parentPath) throws Exception {
        String objectName = userId + File.separator + parentPath + File.separator + uploadFile.getOriginalFilename();
        System.out.println(objectName);
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .stream(uploadFile.getInputStream(), uploadFile.getSize(), -1)
                .object(objectName)
                .contentType(uploadFile.getContentType())
                .build());
        return objectName;
    }


    public boolean uploadObject(File uploadFile, Long userId, String parentPath) throws Exception {
        String objectName = userId + File.separator + parentPath + File.separator + uploadFile.getName();
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .stream(Files.newInputStream(uploadFile.toPath()), uploadFile.length(), -1)
                .object(objectName)
                .build()).wait();
        return true;
    }

    public boolean isObjectExist(String res) throws Exception {
        StatObjectResponse statObject = minioClient.statObject(StatObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(res)
                .build());
        if (statObject != null) {
            return true;
        }
        return false;
    }

    public String getUrl(String fileName) throws Exception {
        String getUrlPath = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .method(Method.GET)
                .build());
        return getUrlPath;
    }

    public GetObjectResponse getObject(FileSearchRequest fileSearchRequest) throws Exception {
        return getObject(fileSearchRequest.getUserId(), fileSearchRequest.getParentPath(), fileSearchRequest.getFileName());
    }

    public GetObjectResponse getObject(Long userId, String parentPath, String fileName) throws Exception {
        String objectName = userId
                + File.separator + parentPath
                + File.separator + fileName;
        return minioClient.getObject(GetObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(objectName)
                .build());
    }
}
